﻿using System;
public static class GlobalMembers
{





    public static int level(char order)
    {
        switch ((char)order)
        {
            case '+':
                return 1;
            case '-':
                return 1;
                break;
            case '*':
                return 2;
            case '/':
                return 2;
                break;
            case '^':
                return 3;
                break;
            case ')':
                return 0;
                break;
            case '(':
                return 0;
                break;
            default:
                return -1;
        }
    }

    public static double compute(double a, double b, char operater)
    {
        switch ((char)operater)
        {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                {
                    if (b > -(10e-8) && b < (10e-8))
                    {
                        Console.Write("divided by zero!");
                        Console.Write("\n");
                        System.Environment.Exit(0);
                        return 0;
                    }
                    else
                        return a / b;
                }
            case '^':
                return (sizeof(double) > 4) ? Math.Pow(a, b) : (int)Math.Pow(a, b);
        }
        return 0;
    }

    unsafe public static double express(string midorder)
    {
       // String* Midorder= &midorder;
       // bool numberstart = true; //标记数字避免atoi重复执行
        bool flag = false;
        LinkStack<char> operater = new LinkStack<char>();
        LinkStack<double> operand = new LinkStack<double>();
        int operandlength = 0;
        for (int i = 0; i < midorder.Length; i++)
        {
            ;
            if (midorder[i] >= '0' && midorder[i] <= '9' ||midorder[i]=='.')
            {
                operandlength++;
                //            cout<<midorder[i]<<endl;
            }
            else if (midorder[i] < '0' || midorder[i] > '9')
            {
                //numberstart = false;
                //Console.Write("{0}",midorder[i]);
               if(operandlength>0) operand.Push((sizeof(double) > 4) ? Convert.ToDouble(midorder.Substring(i-operandlength,operandlength)) : Convert.ToInt32(midorder.Substring(i-operandlength,operandlength)));
                operandlength = 0;
                if (midorder[i] == '\0') break;
                if (level(midorder[i]) == -1)
                {
                    //Console.Write("\n{0},{1}", midorder[i],(int)midorder[i]);
                    //Console.Read();
                    Console.Write("invalid input");
                    Console.Write("\n");
                    System.Environment.Exit(1);
                }
                //numberstart = true;
                if (operater.Empty() || (level(midorder[i]) > level(operater.GetTop()))) //两表达式顺序不可更改
                {
                    operater.Push(midorder[i]);
                    //                cout<<"1:"<<midorder[i]<<endl;
                    continue;
                }
                if (midorder[i] == '(')
                {
                    operater.Push(midorder[i]);
                    continue;
                }
                while (level(midorder[i]) <= level(operater.GetTop()))
                {
                    if (operater.GetTop() == '(' && midorder[i] == ')')
                    {
                        operater.Pop();
                        break;
                    }
                    //                else if(operater.GetTop()=='(')
                    //                {
                    //                     operater.Push(midorder[i]);
                    //                     cout<<midorder[i]<<endl;
                    //                     break;
                    //                }
                    double b = operand.Pop();
                    double a = operand.Pop();
                    char order = operater.Pop();
                    //                cout<<a<<order<<b<<endl;
                    //                cout<<midorder[i]<<operater.GetTop()<<endl;
                    operand.Push(compute(a, b, order));
                    //                cout<<"="<<operand.GetTop()<<endl;
                    //                operater.display();
                    //                operand.display();
                    //                cout<<endl;
                    if (midorder[i] != ')')
                        flag = true;
                    else
                        flag = false;
                }
                if (flag)
                {
                    operater.Push(midorder[i]);
                    //                cout<<"2:"<<midorder[i]<<endl;
                    flag = false;
                }

            }
        }
        while (!operater.Empty())
        {
            double b = operand.Pop();
           // Console.Write("\n{0},{1}", b,(int)b);
            double a = operand.Pop();
           // Console.Write("\n{0},{1}", a,(int)a);
            //        cout<<a<<' '<<b<<endl;
            char order = operater.Pop();
            //Console.Write("\n{0},{1}", order,(int)order);
            operand.Push(compute(a, b, order));
        }
        return operand.GetTop();
    }


    internal static int Main()
    {
        char[] temp=new char [200];
        for (int i = 0; i < 200; i++)
        {
            temp[i] = (char)Console.Read();
            if (temp[i] == ' ' || temp[i] == '#')
            {
                temp[i] = '\0';
                i--;
                continue;
            }
            else if (temp[i] == '\n'||temp[i]=='\r')
            {
                temp[i] = '\0' ;
                break;
            }
        }
        string midorder = new string(temp);
        Console.Write(express(midorder));
        Console.Read();
        Console.Read();
        return 0;
    }
}


public class Node<DT>
{
    public DT data ;
    public Node<DT> next;
    public Node() {; }
}



unsafe public class LinkStack<DT>
{

    public LinkStack()
    {
        top = null;
    }
    public void Dispose()
    {
        Node<DT> tem;
        if (!Empty())
            for (tem = top.next; tem != null; tem = tem.next)
            {

                top = tem;
            }
    }
    public void Push(DT x)
    {
        Node<DT> p = new Node<DT>();
        p.data = x;
        p.next = top;
        top = p;
    }
    public DT Pop()
    {
        DT x = top.data;
        Node<DT> p = top.next;
        //top.Dispose();
        top = p;
        return x;
    }
    public DT GetTop()
    {
        if (top != null)
            return top.data;
        else
        {
            Console.WriteLine("empty");
            Console.Read();
            Console.Read();
            System.Environment.Exit(0);
            return default(DT);
        }
    }
    public bool Empty()
    {
        return (top == null);
    }
    public void display()
    {
        for (Node<DT> i = top; i != null; i = i.next)
        {
            Console.Write(i.data);
            Console.Write(" ");
        }
    }
    private Node<DT> top;
}  
    



internal sealed class DefineConstants
{
    public const int MAX_SIZE = 100;
}